package com.ibeeking.found.file.rest.controller.v1;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.ibeeking.found.common.annotation.LoginUser;
import com.ibeeking.found.common.entity.CurrentUser;
import com.ibeeking.found.common.utils.UserUtils;
import com.ibeeking.found.file.rest.service.IFileService;
import com.ibeeking.found.file.rest.service.IUserFileService;
import com.ibeeking.found.file.rest.service.component.FileDealComp;
import com.ibeeking.found.file.rest.service.office.documentserver.managers.history.HistoryManager;
import com.ibeeking.found.file.rest.service.office.documentserver.models.enums.Action;
import com.ibeeking.found.file.rest.service.office.documentserver.models.enums.Type;
import com.ibeeking.found.file.rest.service.office.documentserver.models.filemodel.FileModel;
import com.ibeeking.found.file.rest.service.office.entities.UserEntity;
import com.ibeeking.found.file.rest.service.office.services.configurers.FileConfigurer;
import com.ibeeking.found.file.rest.service.office.services.configurers.wrappers.DefaultFileWrapper;
import com.ibeeking.found.file.service.common.dos.FileDO;
import com.ibeeking.found.file.service.common.dos.UserFileDO;
import com.ibeeking.found.file.service.common.param.EditOfficeFileParam;
import com.ibeeking.found.file.service.common.param.PreviewOfficeFileParam;
import com.ibeeking.nematos.constants.enums.OperateLogTypeEnum;
import com.ibeeking.nematos.exception.BusinessException;
import com.ibeeking.nematos.file.oss.factory.FileOpFactory;
import com.ibeeking.nematos.file.oss.operation.download.domain.DownloadFile;
import com.ibeeking.nematos.log.annotation.Log;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Locale;
import java.util.Scanner;
/**
 * @ClassName OfficeController
 * @Description 该接口为Onlyoffice文件操作接口，主要用来做一些文档的编辑，浏览等
 * @Author ibeeking
 * @Date 2021-06-02 18:15
 **/
@RestController
@Slf4j
@RequestMapping({"/office/v1"})
public class OfficeController {
    public static final String CURRENT_MODULE = "Onlyoffice文件操作接口";

    @Resource
    private FileOpFactory fileOpFactory;

    @Resource
    private FileDealComp fileDealComp;

    @Value("${files.docservice.deployment.host}")
    private String deploymentHost;

    @Value("${files.docservice.deployment.port}")
    private String port;

    @Value("${files.storage-type}")
    private Integer storageType;

    @Value("${files.docservice.url.site}")
    private String docserviceSite;

    @Value("${files.docservice.url.api}")
    private String docserviceApiUrl;

    @Resource
    private FileConfigurer<DefaultFileWrapper> fileConfigurer;

    @Resource
    private IFileService fileService;

    @Resource
    private IUserFileService userFileServiceImpl;

    @Resource
    private HistoryManager historyManager;

    @Log(logType = OperateLogTypeEnum.QUERY, describe = "预览office文件")
    @PostMapping(value = "/previewofficefile")
    public Object previewOfficeFile(@LoginUser CurrentUser loginUser, @RequestBody PreviewOfficeFileParam previewOfficeFileDTO, HttpServletRequest request) {
        try {
            String token = request.getHeader("token");
            String previewUrl = request.getScheme() + "://" + deploymentHost + ":" + port + "/filetransfer/preview?userFileId=" + previewOfficeFileDTO.getUserFileId() + "&isMin=false&shareBatchNum=undefined&extractionCode=undefined&token=" + token;
            UserFileDO userFile = userFileServiceImpl.getById(previewOfficeFileDTO.getUserFileId());
            String userId = UserUtils.getStringUserId();

            Action action = Action.view;
            Type type = Type.desktop;
            Locale locale = new Locale("zh");
            FileModel fileModel = fileConfigurer.getFileModel(
                    DefaultFileWrapper
                            .builder()
                            .userFile(userFile)
                            .type(type)
                            .lang(locale.toLanguageTag())
                            .action(action)
                            .userEntity(new UserEntity(loginUser))
                            .actionData(previewUrl)
                            .build()
            );

            JSONObject jsonObject = new JSONObject();
            jsonObject.put("file",fileModel);
//            jsonObject.put("fileHistory", historyManager.getHistory(fileModel.getDocument()));  // get file history and add it to the model
            jsonObject.put("docserviceApiUrl", docserviceSite + docserviceApiUrl);
            jsonObject.put("reportName",userFile.getFileName());
            return jsonObject;
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new BusinessException("服务器错误！");
        }
    }

    @Log(logType = OperateLogTypeEnum.MODIFY, describe = "编辑office文件")
    @GetMapping(value = "/editofficefile")
    public Object editOfficeFile(@LoginUser CurrentUser loginUser, @RequestBody EditOfficeFileParam editOfficeFileDTO, HttpServletRequest request) {
        String token = request.getHeader("token");
        String previewUrl = request.getScheme() + "://" + deploymentHost + ":" + port + "/filetransfer/preview?userFileId=" + editOfficeFileDTO.getUserFileId() + "&isMin=false&shareBatchNum=undefined&extractionCode=undefined&token=" + token;
        log.info("editOfficeFile");
        try {
            UserFileDO userFile = userFileServiceImpl.getById(editOfficeFileDTO.getUserFileId());
            Action action = Action.edit;
            Type type = Type.desktop;
            Locale locale = new Locale("zh");
            FileModel fileModel = fileConfigurer.getFileModel(
                    DefaultFileWrapper
                            .builder()
                            .userFile(userFile)
                            .type(type)
                            .lang(locale.toLanguageTag())
                            .action(action)
                            .userEntity(new UserEntity(loginUser))
                            .actionData(previewUrl)
                            .build()
            );
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("file",fileModel);
            jsonObject.put("docserviceApiUrl", docserviceSite + docserviceApiUrl);
            jsonObject.put("reportName",userFile.getFileName());
            return jsonObject;
        } catch (Exception e) {
            log.error(e.getMessage());
            throw new BusinessException("服务器错误！");
        }
    }


    @PostMapping(value = "/IndexServlet")
    public void IndexServlet(@LoginUser CurrentUser loginUser, HttpServletRequest request, HttpServletResponse response) throws IOException {
        if (loginUser == null || loginUser.getId() == null) {
            throw new BusinessException("无法获取登录用户信息！");
        }

        PrintWriter writer = response.getWriter();
        Scanner scanner = new Scanner(request.getInputStream()).useDelimiter("\\A");
        String body = scanner.hasNext() ? scanner.next() : "";

        JSONObject jsonObj = JSON.parseObject(body);
        log.info("===saveeditedfile:" + jsonObj.get("status")); ;
        String status = jsonObj != null ? jsonObj.get("status").toString() : "";
        if ("2".equals(status) || "6".equals(status)) {
            String type = request.getParameter("type");
            String downloadUri = (String) jsonObj.get("url");

            if("edit".equals(type)){ //修改报告
                String userFileId = request.getParameter("userFileId");
                UserFileDO userFile = userFileServiceImpl.getById(userFileId);
                FileDO fileBean = fileService.getById(userFile.getFileId());
                Long pointCount = fileService.getFilePointCount(userFile.getFileId());
                String fileUrl = fileBean.getFileUrl();
                if (pointCount > 1) {
                    fileUrl = fileDealComp.copyFile(fileBean, userFile);
                }

                URL url = new URL(downloadUri);
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();

                try {
                    InputStream stream = connection.getInputStream();
                    fileDealComp.saveFileInputStream(fileBean.getStorageType(), fileUrl, stream);

                } catch (Exception e) {
                    log.error(e.getMessage());
                } finally {

                    int fileLength = connection.getContentLength();
                    log.info("当前修改文件大小为：" + (long) fileLength);

                    DownloadFile downloadFile = new DownloadFile();
                    downloadFile.setFileUrl(fileBean.getFileUrl());
                    InputStream inputStream = fileOpFactory.getDownloader(fileBean.getStorageType()).getInputStream(downloadFile);
                    String md5Str = DigestUtils.md5Hex(inputStream);

                    fileService.updateFileDetail(userFile.getUserFileId(), md5Str, fileLength);
                    connection.disconnect();
                }
            }
        }

        if("3".equals(status)||"7".equals(status)) {//不强制手动保存时为6,"6".equals(status)
            log.debug("====保存失败:");
            writer.write("{\"error\":1}");
        }else {
            log.debug("状态为：0") ;
            writer.write("{\"error\":" + "0" + "}");

        }
    }

}